﻿using Common;
using Common.HttpRequest;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using SystemService;
using Newtonsoft.Json;
using Common.Swagger;
using Ocelot.Values;
using Ocelot.Provider.Consul;
using Ocelot.ServiceDiscovery.Providers;
using System.Text;
using Ocelot.ServiceDiscovery;
using Ocelot.Configuration;
using Ocelot.Logging;
using Ocelot.Configuration.Repository;
using Ocelot.Cache;
using Ocelot.Configuration.File;
using Common.ResultFormat;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using IdentityServer4.Models;
using Common.Identity;

namespace Gateway.AuthorizationFilter
{
    /// <summary>
    /// 网关权限过滤
    /// </summary>
    public static class CustomAuthorizationFilter
    {
        //private static SystemUrlService systemUrlService;

        //static CustomAuthorizationFilter()
        //{
        //    systemUrlService = Application.GetService<SystemUrlService>();
        //}
        /// <summary>
        /// 权限过滤
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public static HttpContext UrlFiter(HttpContext context)
        {
            string url = context.Request.Path.Value.ToLower();
            SystemUrlService systemUrlService = context.RequestServices.GetService(typeof(SystemUrlService)) as SystemUrlService;
            var entity = SwaggerReadSummary.ReadSummary(context);
            if (entity!=null)
            {
                systemUrlService.CheckAndAdd(new SystemEntity.SystemUrlEntity() { Url = url, Name = entity.Name, ApplicationName = entity.ApplicationName, ControllerName = entity.ControllerName });
            }
            if (url == "/" || url.EndsWith("swagger.json") || url.Contains(".well-known/openid-configuration") || url.Contains("/api/login/loginin") || url.Contains("swagger/index.html") || url.Contains("/favicon.ico")||url.Contains("/swagger/")||url.Contains("/connect/token")||url.Contains("/profiler/"))
            {
                return context;
            }
            else
            {
                Console.WriteLine(context.TraceIdentifier + url);
                string authorization = string.Empty;
                if (context.Request.Headers.ContainsKey("authorization"))
                {
                    authorization = context.Request.Headers["authorization"].ToString();
                }
                else if (context.Request.Query.ContainsKey("token"))
                {
                    authorization = context.Request.Query["token"];
                }
                else if (context.Request.Query.ContainsKey("authorization"))
                {
                    authorization = context.Request.Query["authorization"];
                }
                if (string.IsNullOrEmpty(authorization))
                {
                    context.Response.WriteAsJsonAsync(Result.Error("没权限:"+ url), typeof(Result));
                    context.Response.CompleteAsync();
                }
                else
                {
                    if (authorization.StartsWith("Bearer "))
                    {
                        authorization = authorization.Substring("Bearer ".Length).Trim();
                    }                    

                    JwtSecurityToken jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(authorization);
                    if (jwtToken != null)
                    {
                        #region 检查令牌对象内容
                        DateTime now = DateTime.UtcNow;
                        DateTime refreshTime = jwtToken.ValidFrom;
                        var claimlist = jwtToken?.Payload.Claims as List<Claim>;
                        var id = jwtToken.Id;
                        string userName = jwtToken.Subject;
                        string userId = jwtToken.Id;
                        refreshTime = refreshTime.Add(TimeSpan.FromSeconds(OAuthServerConfig.ExpireIn));
                        if (now > refreshTime)
                        {
                            //已过期，需要重新登录
                            context.Response.WriteAsJsonAsync(Result.Error("已过期，请重新登录:" + url), typeof(Result));
                            context.Response.CompleteAsync();
                        }
                        else
                        {
                            
                        }
                        #endregion
                    }
                    else
                    {
                        //token格式不正确
                        context.Response.WriteAsJsonAsync(Result.Error("没权限:" + url), typeof(Result));
                        context.Response.CompleteAsync();
                    }
                    return context;
                }
            }
            return context;
        }
    }
}